﻿using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using Citi.GocAttributes.Domain;
using Citi.GocAttributes.WebUI.Models;
using Webdiyer.WebControls.Mvc;
using OfficeOpenXml;
using System.IO;
using System;

namespace Citi.GocAttributes.WebUI.Controllers
{
    public class GocController : Controller
    {
        public ActionResult Search(int page = 1, GocFilterModel filterModel = null)
        {
            var gocs = new Goc().SelectAllActive<Goc>()
                                .GroupBy(c => c.GocAttribute)
                                .Select(g => g.OrderByDescending(c => c.ReferenceDate).First())
                                .Select(x => x).ToList();

            return FilterGoc(page, filterModel, gocs);
        }

        private ActionResult FilterGoc(int page, GocFilterModel filterModel, List<Goc> gocs)
        {
            if (filterModel != null)
                gocs = Filter(gocs, filterModel);

            var pagedList = new PagedList<Goc>(gocs, page, 50);

            if (Request.IsAjaxRequest())
                return PartialView("List", new GocOptionModel { Gocs = pagedList, Exception = filterModel != null && filterModel.Exception });

            return View(pagedList);
        }

        public ActionResult Exceptions(int page = 1, GocFilterModel filterModel = null)
        {
            var gocs = new Goc().SelectGocsRuleException();

            return FilterGoc(page, filterModel, gocs);
        }

        public ActionResult ApplyRule()
        {
            var rules = new Rule().GetActiveRulesButException();

            ViewBag.Rules = rules.Select(x => new SelectListItem { Text = x.Name, Value = x.Id.ToString() });

            return PartialView();
        }

        public List<Goc> Filter(List<Goc> gocs, GocFilterModel filterModel)
        {
            gocs.RemoveAll(x => !string.IsNullOrEmpty(filterModel.CorpCode) && !x.CorpCode.ToUpper().Contains(filterModel.CorpCode.ToUpper()));
            gocs.RemoveAll(x => filterModel.CountryId != 0 && x.CountryId != filterModel.CountryId);
            gocs.RemoveAll(x => !string.IsNullOrEmpty(filterModel.ExpenseCode) && !x.ExpenseCode.ToUpper().Contains(filterModel.ExpenseCode.ToUpper()));
            gocs.RemoveAll(x => filterModel.FrsBuId != 0 && x.FrsBuId != filterModel.FrsBuId);
            gocs.RemoveAll(x => filterModel.FrsOuId != 0 && x.FrsOuId != filterModel.FrsOuId);
            gocs.RemoveAll(x => !string.IsNullOrEmpty(filterModel.GocAttribute) && !x.GocAttribute.ToUpper().Contains(filterModel.GocAttribute.ToUpper()));
            gocs.RemoveAll(x => !string.IsNullOrEmpty(filterModel.Lvid) && !x.LegalVehicle.Code.ToUpper().Contains(filterModel.Lvid.ToUpper())
                && !x.LegalVehicle.Description.ToUpper().Contains(filterModel.Lvid.ToUpper()));
            gocs.RemoveAll(x => !string.IsNullOrEmpty(filterModel.LocalCostCode) && !x.LocalCostCode.ToUpper().Contains(filterModel.LocalCostCode.ToUpper()));
            gocs.RemoveAll(x => !string.IsNullOrEmpty(filterModel.LongDescription) && !x.LongDescription.ToUpper().Contains(filterModel.LongDescription.ToUpper()));

            var functionCode = filterModel.FunctionId != 0 ? new Function().SelectById<Function>(filterModel.FunctionId).Code : string.Empty;
            var managedSegmentCode = filterModel.ManagedSegmentId != 0 ? new ManagedSegment().SelectById<ManagedSegment>(filterModel.ManagedSegmentId).Code : 0;

            gocs.RemoveAll(x => filterModel.ManagedSegmentId != 0 && (x.ManagedSegment == null || x.ManagedSegment.Code != managedSegmentCode));
            gocs.RemoveAll(x => filterModel.FunctionId != 0 && (x.Function == null || x.Function.Code != functionCode));
            gocs.RemoveAll(x => !string.IsNullOrEmpty(filterModel.Manager) && !x.Manager.ToUpper().Contains(filterModel.Manager.ToUpper()));

            var ruleName = filterModel.RuleId.HasValue ? new Rule().SelectById<Rule>(filterModel.RuleId.Value).Name : string.Empty;

            gocs.RemoveAll(x => filterModel.RuleId != null && filterModel.RuleId != 0 && (!x.GocRules.Any() || x.GocRules.Any(y => y.Rule.Name != ruleName)));
            gocs.RemoveAll(x => !string.IsNullOrEmpty(filterModel.SidCode) && !x.Sid.Description.ToUpper().Contains(filterModel.SidCode.ToUpper()));

            var typeRuleResultName = filterModel.TypeRuleResultId != 0 ? new TypeRuleResult().SelectById<TypeRuleResult>(filterModel.TypeRuleResultId).Value : string.Empty;

            //gocs.RemoveAll(x => filterModel.TypeRuleResultId != 0 && x.GetRuleResult(DatabaseEnums.TypeResultType.DeckRegional1) != typeRuleResultName);

            return gocs;
        }

        public ActionResult NewGocs(int month = 0, int year = 0, int page = 1)
        {
            ViewBag.Months = new List<SelectListItem>
                {
                    new SelectListItem{Text = DateTime.Today.AddMonths(-3).ToString("MMMMM"),Value = DateTime.Today.AddMonths(-3).Month.ToString()},
                    new SelectListItem{Text = DateTime.Today.AddMonths(-2).ToString("MMMMM"),Value = DateTime.Today.AddMonths(-2).Month.ToString()},
                    new SelectListItem{Text = DateTime.Today.AddMonths(-1).ToString("MMMMM"),Value = DateTime.Today.AddMonths(-1).Month.ToString()},
                    new SelectListItem{Text = DateTime.Today.ToString("MMMMM"),Value = DateTime.Today.Month.ToString(), Selected = true}
                };

            var years = new List<SelectListItem>
                {
                    new SelectListItem{Text = DateTime.Today.Year.ToString(),Value = DateTime.Today.Year.ToString()}
                };

            if (DateTime.Today.AddMonths(-3).Year != DateTime.Today.Year)
                years.Add(new SelectListItem { Text = (DateTime.Today.Year - 1).ToString(), Value = (DateTime.Today.Year - 1).ToString() });

            ViewBag.Years = years;

            return NewGocsList(month == 0 ? DateTime.Today.Month : month, year == 0 ? DateTime.Today.Year : year, page);
        }

        [HttpPost]
        public ActionResult NewGocsList(int month, int year, int page = 1)
        {
            var gocs = new Goc().SelectAllActive<Goc>().Where(x => x.ReferenceDate.Month == month && x.ReferenceDate.Year == year).ToList();

            //return PartialView(gocs);
            return FilterGoc(page, null, gocs);
        }

        [HttpPost]
        public ActionResult Filter(GocFilterModel model)
        {
            return model.Exception
                ? Exceptions(model.Page == 0 ? 1 : model.Page, model)
                : Search(model.Page == 0 ? 1 : model.Page, model);
        }

        public ActionResult RemoveRule(int id)
        {
            var goc = new Goc().SelectById<Goc>(id);

            //goc.GocRules.Clear();
            goc.GocRules.ToList().ForEach(x => goc.GocRules.Remove(x));
            goc.Save(goc);

            return Search(1, new GocFilterModel { Exception = false });
        }

        public ActionResult Report()
        {
            return View();
        }

        public ActionResult Edit(int id)
        {
            var goc = new Goc().SelectById<Goc>(id);

            return View(goc);
        }

        [HttpPost]
        public ActionResult Edit(Goc model)
        {
            var goc = new Goc().SelectById<Goc>(model.Id);
            goc.OUC = model.OUC;
            goc.Corinth = model.Corinth;
            goc.Project = model.Project;
            goc.OTHead = model.OTHead;

            goc.Save(goc);

            return RedirectToAction("Search");
        }

        public ActionResult GenerateGocAttributesReport(int month, int year)
        {
            //var model = new Goc().GetGocsByReferenceDate(new DateTime(year, month, 1));
            var pathToSave = Server.MapPath(@"~\Outputs\");

            using (Citi.SecurityHelper.ImpersonateCitiUser.GetImpersonateUser(@"lac\lac_bra_ftools", @"lac\lac_bra_ftools", "Ferrari3k10"))
            {
                var file = new Goc().GenerateReport(new DateTime(year, month, 1), pathToSave);

                //using (var excelPackage = new ExcelPackage(new FileInfo(@"\\gruvnascti0016.wlb.lac.nsroot.net\DATA_GRP1\FTOOLS\Apps\GOCAttributes\GOCTemplate.xlsx"), true))
                //{
                //    var worksheet = excelPackage.Workbook.Worksheets[1];

                //    int row = 3;

                //    foreach (var item in model)
                //    {
                //        worksheet.Cells[row, 1].Value = item.GocAttribute;

                //        int gocAsNumber;

                //        worksheet.Cells[row, 2].Value = int.TryParse(item.GocAttribute, out gocAsNumber) ? gocAsNumber.ToString() : item.GocAttribute;
                //        worksheet.Cells[row, 3].Value = item.LongDescription;
                //        worksheet.Cells[row, 4].Value = item.ExpenseCode;
                //        worksheet.Cells[row, 5].Value = item.CorpCode;
                //        worksheet.Cells[row, 6].Value = item.Status;
                //        worksheet.Cells[row, 7].Value = item.UpdatedDate;
                //        worksheet.Cells[row, 8].Value = item.Sid.Description;
                //        worksheet.Cells[row, 9].Value = item.LocalCostCode;
                //        worksheet.Cells[row, 10].Value = item.Manager;
                //        worksheet.Cells[row, 11].Value = item.FrsBu.Code;
                //        worksheet.Cells[row, 12].Value = item.FrsBu.Description;
                //        worksheet.Cells[row, 13].Value = item.FrsOu.Code;
                //        worksheet.Cells[row, 14].Value = item.FrsOu.Description;
                //        worksheet.Cells[row, 15].Value = item.Function.Code;
                //        worksheet.Cells[row, 16].Value = item.Function.Description;
                //        worksheet.Cells[row, 17].Value = item.LegalVehicle.Code;
                //        worksheet.Cells[row, 18].Value = item.LegalVehicle.Description;
                //        worksheet.Cells[row, 19].Value = item.ManagedGeography.Code;
                //        worksheet.Cells[row, 20].Value = item.ManagedGeography.Description;
                //        worksheet.Cells[row, 21].Value = item.ManagedSegment.Code;
                //        worksheet.Cells[row, 22].Value = item.ManagedSegment.Description;

                //        var managedSegment = item.ManagedSegment;
                //        for (int i = item.ManagedSegment.TreeLevel; i >= 0; i--)
                //        {
                //            worksheet.Cells[row, 22 + i].Value = managedSegment.Description;

                //            if (managedSegment.ParentId != null)
                //                managedSegment = managedSegment.Parent;
                //            else
                //                break;
                //        }

                //        var function = item.Function;
                //        for (int i = item.Function.TreeLevel; i >= 0; i--)
                //        {
                //            worksheet.Cells[row, 35 + i].Value = function.Description;

                //            if (function.ParentId != null)
                //                function = function.Parent;
                //            else
                //                break;
                //        }

                //        worksheet.Cells[row, 45].Value = item.GetRuleResult(DatabaseEnums.TypeResultType.OTFunctionL0) == "-" 
                //            ? "Non-O&T" 
                //            : item.GetRuleResult(DatabaseEnums.TypeResultType.OTFunctionL0);
                //        worksheet.Cells[row, 46].Value = item.GetRuleResult(DatabaseEnums.TypeResultType.Business);
                //        worksheet.Cells[row, 47].Value = item.GetRuleResult(DatabaseEnums.TypeResultType.Business1);
                //        worksheet.Cells[row, 48].Value = item.GetRuleResult(DatabaseEnums.TypeResultType.Area);
                //        worksheet.Cells[row, 49].Value = item.GetRuleResult(DatabaseEnums.TypeResultType.DeckRegional);
                //        worksheet.Cells[row, 50].Value = item.GetRuleResult(DatabaseEnums.TypeResultType.DeckRegional1);
                //        worksheet.Cells[row, 51].Value = item.GetRuleResult(DatabaseEnums.TypeResultType.Local);
                //        worksheet.Cells[row, 52].Value = item.GetRuleResult(DatabaseEnums.TypeResultType.FPAManager);
                //        worksheet.Cells[row, 53].Value = item.GetRuleResult(DatabaseEnums.TypeResultType.FPAAnalyst);
                //        worksheet.Cells[row, 54].Value = item.OUC;
                //        worksheet.Cells[row, 55].Value = item.Project;
                //        worksheet.Cells[row, 56].Value = item.Corinth ? "CORINTH" : "-";
                //        worksheet.Cells[row, 57].Value = item.RuleId;

                //        for (int i = 1; i < 56; i++)
                //        {
                //            if (worksheet.Cells[row, i].Value == null)
                //                worksheet.Cells[row, i].Value = "-";
                //        }

                //        row++;
                //    }

                //    var file = string.Concat(pathToSave, "GOCAttributes", DateTime.Now.ToString("yyyyMMdd"), ".xlsx");
                //    Directory.GetFiles(pathToSave).ToList().ForEach(System.IO.File.Delete);

                //    var bin = excelPackage.GetAsByteArray();
                //    System.IO.File.WriteAllBytes(file, bin);

                return File(file, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "GOCAttributes.xlsx");
            }
            //}
        }
    }
}
